/* 
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */


#include <QFont>
#include "threaditemmodel.h"
#include "components/chan.h"
#include "components/board.h"
#include "components/thread.h"
#include "log.h"

ThreadItemModel::ThreadItemModel(eMode mode, Wishmaster::Board* board, QObject* parent) : QAbstractListModel(parent), m_board(board)
{
	if(!m_deadThread.load(":/wishmaster/images/skull.png"))
	{
		log(llWarning, "Unable to find skull.png image");
	}
	else
	{
		m_deadThread = m_deadThread.scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
	}
	m_mode = mode;
}

ThreadItemModel::~ThreadItemModel()
{
}

int ThreadItemModel::rowCount(const QModelIndex &parent) const
{
	if(!m_board)
		return 0;
	ThreadCollector* threads = threadsByMode(m_mode);
	return threads->count();
}

QVariant ThreadItemModel::data(const QModelIndex &index, int role) const
{
	if(!m_board)
		return QVariant();

	if(!index.isValid())
		return QVariant();

	Wishmaster::EntityCollector<Wishmaster::ThreadPtr, Wishmaster::ThreadId>* threads = threadsByMode(m_mode);

	if(index.row() >= threads->count())
		return QVariant();

	Wishmaster::ThreadPtr thread = threads->getNth(index.row());

	switch(role)
	{
		case Qt::DisplayRole:
			{
				QString str;
				if(thread->getPostsCount() == 0)
					str = QString("[???] ") + thread->getName();
				else
					str = QString("[%1] ").arg(thread->getPostsCount()) + thread->getName();

				return QVariant(str);
			}
		case ThreadIdRole:
			{
				return QVariant((uint)thread->id().threadNumericId());
			}
		case Qt::DecorationRole:
			{
				return QVariant(thread->leaderPic());
			}
		case ThreadFlags:
			{
				int result = 0;
				if(!thread->flag(Wishmaster::Thread::Alive))
					result |= ThreadDead;
				if(thread->visibility() == Wishmaster::Hide ||
				   thread->visibility() == Wishmaster::HideForever)
					result |= ThreadHidden;
				if(thread->flag(Wishmaster::Thread::Watched))
					result |= ThreadWatch;
				if(thread->flag(Wishmaster::Thread::Responded))
					result |= ThreadResponded;
				return result;
			}
		case BoardRole:
			{
				return QVariant::fromValue((void*)m_board);
			}
		case Qt::FontRole:
			{
				if(thread->state() == Wishmaster::Thread::sNewThread ||
						thread->state() == Wishmaster::Thread::sNewPosts)
				{
					QFont font;
					font.setBold(true);
					return font;
				}
				else
				{
					return QFont();
				}
			}
		case Qt::ForegroundRole:
			{
				if(thread->state() == Wishmaster::Thread::sNewPosts)
					return QColor(0, 0, 255);
				return QColor(0, 0, 0);
			}
		case UniqueIdRole:
			{
				return QString("%1/%2/%3").arg(m_board->getParent()->getHost(), m_board->name(), QString::number(thread->id().threadNumericId()));
			}
	case FullThreadIdRole:
			{
				return QVariant::fromValue(thread->id());
			}
		default:
			return QVariant();
	}
}

void ThreadItemModel::refresh()
{
	if(!m_board)
		return;
	reset();
}

void ThreadItemModel::setBoard(Wishmaster::Board* board)
{
	m_board = board;
	refresh();
}

int ThreadItemModel::getThreadRow(const Wishmaster::ThreadId& threadId)
{
	return m_board->threadPosition(threadId);
}

int ThreadItemModel::page() const
{
	return m_page;
}

void ThreadItemModel::setPage(int p)
{
	m_page = p;
}

void ThreadItemModel::update(int row)
{
	QModelIndex index = createIndex(row, 0, 0);
	emit dataChanged(index, index);
}

Wishmaster::EntityCollector<Wishmaster::ThreadPtr, Wishmaster::ThreadId>* ThreadItemModel::threadsByMode(eMode mode) const
{
	switch(mode)
	{
		case mHidden:
			return m_board->hiddenThreads();

		case mArchive:
			return m_board->archivedThreads();

		case mVisible:
		default:
			return m_board->visibleThreads();
	}
}

